package com.dap.dao.model;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.dap.utils.DeepFieldCopy;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 分页查询结果集
 */
public class Page<T> implements Serializable {
    private long totalCount;
    private int pageSize;
    private int pageIndex;
    private int totalPages;
    private List<T> elements;


    /**
     * 根据总数量和每页数量 计算 总页数
     * */
    public static int computeTotalPages(long totalCount, int pageSize) {
        int totalPages = 0;
        if (pageSize > 0) {
            totalPages = (int) (totalCount / pageSize);
            if (totalCount % pageSize != 0)
                ++totalPages;
        }
        return totalPages;
    }


    public Page() {}
    public Page(long totalCount, int pageSize, int pageIndex, List<T> elements) {
        this.totalCount = totalCount;
        this.pageSize = pageSize;
        this.pageIndex = pageIndex;

        this.totalPages = computeTotalPages(totalCount, pageSize);

        this.elements = elements;
    }

    /**
     * 根据 全部数据 和分页参数, 生成分页数据
     * */
    public static <T> Page<T> generatePageFromTotalData(int pageSize, int pageIndex, List<T> totalData) {
        if (pageSize <= 0)
            pageSize = 10;
        if (pageIndex < 1)
            pageIndex = 1;

        Page<T> page = new Page<>();

        page.totalCount = totalData.size();
        page.pageSize = pageSize;
        page.pageIndex = pageIndex;

        page.totalPages = computeTotalPages(page.totalCount, pageSize);

        page.elements = new ArrayList<>();
        int start = pageSize*(pageIndex-1);
        if (start < totalData.size()) {
            int end = Math.min(start + pageSize, totalData.size());
            for (int idx = start; idx < end; ++idx) {
                page.elements.add(totalData.get(idx));
            }
        }

        return page;
    }


    public static <FromType, ToType> Page<ToType> fromOtherType(Page<FromType> fromTypePage, Class<ToType> toTypeClass) {
        Page<ToType> toPage = new Page<>();

        toPage.totalCount = fromTypePage.totalCount;
        toPage.pageSize = fromTypePage.pageSize;
        toPage.pageIndex = fromTypePage.pageIndex;
        toPage.totalPages = fromTypePage.totalPages;
        toPage.elements = DeepFieldCopy.transformList(fromTypePage.elements, toTypeClass);

        return toPage;
    }
    public static <FromType, ToType> Page<ToType> fromOtherType(Page<FromType> fromTypePage, Class<ToType> toTypeClass, SerializerFeature... features) {
        Page<ToType> toPage = new Page<>();

        toPage.totalCount = fromTypePage.totalCount;
        toPage.pageSize = fromTypePage.pageSize;
        toPage.pageIndex = fromTypePage.pageIndex;
        toPage.totalPages = fromTypePage.totalPages;
        toPage.elements = DeepFieldCopy.transformList(fromTypePage.elements, toTypeClass, features);

        return toPage;
    }


    public long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(long totalCount) {
        this.totalCount = totalCount;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getPageIndex() {
        return pageIndex;
    }

    public void setPageIndex(int pageIndex) {
        this.pageIndex = pageIndex;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }

    public List<T> getElements() {
        return elements;
    }

    public void setElements(List<T> elements) {
        this.elements = elements;
    }
}
